using Engine;
using Game;

namespace SCIENEW {
    public static class NormalBlockManager {
        public static NormalBlock[] Blocks;

        /// <summary>
        /// 方块字符串ID（合成ID）与其完整值对应表
        /// </summary>
        public static Dictionary<string, int> IdMap;

        public static void Init() {
            Blocks = [
                //机械外壳
                new MachineShellNBlock("BasicMechanicalShell", true),
                new FlaxNBlock("Flax_Top", Color.White, 7, [ItemsBlockManager.GetItemID("FlaxSeed")]),
                new FlaxNBlock("Flax_Stem_Ripened", Color.White, 9, [ItemsBlockManager.GetItemID("FlaxSeed"), ItemsBlockManager.GetItemID("FlaxFiber"), ItemsBlockManager.GetItemID("FlaxFiber")]),
                new FlaxNBlock("Flax_Stem", Color.White, 10, [ItemsBlockManager.GetItemID("FlaxFiber")]),
                //new MachineShellNBlock("高级机械外壳", "AdvancedMechanicalShell", "某些机器或设备的高级外壳。 非常重且耐用。 对挖掘和爆炸都有非常有抗性。 可以用多个钢板制作。", false),
                //new MachineShellNBlock("钛合金机械外壳", "TitaniumAlloyMechanicalShell", "一些机器的高级外壳。通常运用在航天上。", false),
                //金属块
                new MetalNBlock(Materials.Steel),
                new MetalNBlock(Materials.Gold),
                new MetalNBlock(Materials.Silver),
                new MetalNBlock(Materials.Lead),
                new MetalNBlock(Materials.Platinum),
                new MetalNBlock(Materials.Zinc),
                new MetalNBlock(Materials.Stannary),
                new MetalNBlock(Materials.Chromium),
                new MetalNBlock(Materials.Titanium),
                new MetalNBlock(Materials.Nickel),
                new MetalNBlock(Materials.Aluminum),
                new MetalNBlock(Materials.Germanium),
                new MetalNBlock(Materials.FeAlCrAlloy),
                new MetalNBlock(Materials.Brass),
                new MetalNBlock(Materials.Vanadium),
                new MetalNBlock(Materials.Cupronickel),
                //耐火砖
                new StoneTypeNBlock( "FirebrickWall", IndustrialModLoader.IETexture, Color.White, 4),
                //混凝土
                new StoneTypeNBlock("ConcreteWall", IndustrialModLoader.IETexture, Color.White, 20),
                new CokeCoalNBlock(),
            ];

            //初始化ID对应表
            IdMap = new Dictionary<string, int>();
            int itemIndex = 0;
            foreach (var block in Blocks) {
                //生成完整值
                int id = Terrain.MakeBlockValue(BaseNormalBlock.Index, 0, itemIndex++);
                IdMap.Add(block.GetCraftingId(), id);
            }
        }

        public static void LateInit() {
            foreach (var block in Blocks) {
                //创建合成谱
                CraftingRecipesManager.m_recipes.AddRange(block.GenerateProceduralRecipe(GetNormalBlockID(block)));
            }
        }

        /// <summary>
        /// 通过方块完整值获取对应类的实例
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static NormalBlock GetNormalBlock(int value) {
            int index = Terrain.ExtractData(value);
            if(index < Blocks.Length) return Blocks[index];
            return Blocks[0];
        }

        public static NormalBlock GetNormalBlock(string craftingID) => GetNormalBlock(IdMap[craftingID]);

        public static int GetNormalBlockID(string craftingID) => IdMap.ContainsKey(craftingID) ? IdMap[craftingID] : -1;

        public static int GetNormalBlockID(NormalBlock block) => GetNormalBlockID(block.GetCraftingId());

        public static string GetNormalBlockCraftingID(int value) => GetNormalBlock(value).GetCraftingId();

        /// <summary>
        /// 通过材料获取某材料方块实例
        /// </summary>
        /// <param name="material"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T? GetNBlockByMaterial<T>(Materials material) where T : NormalBlock, IMaterialBlock{
            NormalBlock[] items = Blocks.Where(x => x.GetType() == typeof(T)).ToArray();
            foreach (var item in items) {
                IMaterialBlock? materialBlock = item as IMaterialBlock ?? null;
                if(materialBlock != null && materialBlock.GetMaterial() != material) continue;
                return item as T;
            }
            return null;
        }

        /// <summary>
        /// 通过材料获取某方块ID
        /// </summary>
        /// <param name="material"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static int GetNBlockIdByMaterial<T>(Materials material) where T : NormalBlock, IMaterialBlock{
            //特例
            if (material == Materials.Iron) {
                if (typeof(T) == typeof(MetalNBlock)) return IronBlock.Index;
            }
            else if(material == Materials.Copper) {
                if (typeof(T) == typeof(MetalNBlock)) return CopperBlock.Index;
            }
            else if (material == Materials.Germanium) {
                if (typeof(T) == typeof(MetalNBlock)) return SemiconductorBlock.Index;
            }
            //通解
            T? item = GetNBlockByMaterial<T>(material);
            if (item != null) {
                return GetNormalBlockID(item);
            }
            return 0;
        }
    }
}